// MeshImportFilter.cpp
//
//////////////////////////////////////////////////////////////////////

#include "MeshImportFilter.h"
#include "Mesh3D.h"

MeshImportFilter::MeshImportFilter(){

}

MeshImportFilter::~MeshImportFilter(){

}

LIB3D_RETURN MeshImportFilter::operator()(Object3D * root,char * filename){
	Object3D * o;
	Lib3dsNode * p;

	file=lib3ds_file_load(filename);

	if (!file) 
		return LIB3D_ERROR;
	
    lib3ds_file_eval(file,0);

    for (p=file->nodes; p!=0; p=p->next) {
		o=new Object3D();
		root->addChild(o);
      render_node(p,o);
    }

	return LIB3D_OK;
}

void MeshImportFilter::render_node(Lib3dsNode *node,Object3D * o){
    Lib3dsNode *p;
	Object3D * child;
	long color;

	Material material;
	material.diffuse=Vector3D(0.9f,0.1f,0.8f,1.0f);
	material.specular=Vector3D(0.5f,0.5f,0.5f,1.0f);
	material.ambient=Vector3D(0.3f,0.3f,0.3f,1.0f);
	material.shininess=6;

    for (p=node->childs; p!=0; p=p->next) {
		child=new Object3D();
		o->addChild(child);
		render_node(p,child);
    }

	if (node->type==LIB3DS_OBJECT_NODE) {
		if (strcmp(node->name,"$$$DUMMY")==0) 
			return;

		if (!node->user.d) {
			Lib3dsMesh *mesh=lib3ds_file_mesh_by_name(file, node->name);
			ASSERT(mesh);

			if (!mesh)
				return;

			unsigned p;
			Lib3dsVector *normalL=(Lib3dsVector *)malloc(3*sizeof(Lib3dsVector)*mesh->faces);
			
			lib3ds_mesh_calculate_normals(mesh, normalL);
			Mesh3D * g=new Mesh3D();
			o->setVisual(g);
			o->setMaterial(material);

			color=RGBCOLOR(1,1,1);

			if(mesh->texels){
				for(p=0;p<mesh->points;p++)
					g->addVertex(Vertex3D(Point3D(mesh->pointL[p].pos),Vector3D(),mesh->texelL[p][0],mesh->texelL[p][1],color));
			} else {
				for(p=0;p<mesh->points;p++)
					g->addVertex(Vertex3D(Point3D(mesh->pointL[p].pos),Vector3D(),0,0,color));
			}	

			for (p=0; p<mesh->faces; ++p) {
				Lib3dsFace *f=&mesh->faceL[p];
				Lib3dsMaterial *mat=0;
			
				if (f->material[0]) 
						mat=lib3ds_file_material_by_name(file, f->material);

				if (mat) 
					color=RGBCOLOR(mat->diffuse[0],mat->diffuse[1],mat->diffuse[2]);
				else
					color=RGBCOLOR(1,1,1);
				
				g->addFace(Triangle(f->points[0],f->points[1],f->points[2]));
				g->getVertex(f->points[0]).color=color;
				g->getVertex(f->points[1]).color=color;
				g->getVertex(f->points[2]).color=color;
				g->getVertex(f->points[0]).normal=Vector3D(normalL[3*p]);
				g->getVertex(f->points[1]).normal=Vector3D(normalL[3*p+1]);
				g->getVertex(f->points[2]).normal=Vector3D(normalL[3*p+2]);
			}
			free(normalL);
		}
	}
}
